package com.world;

import java.util.ArrayList;


public class Chunk {
	static public final int CHUNK_SIZE = 5;
	static public final float CHUNK_GL_SIZE = 10.0f;
	private ChunkQube[][][] chunkData = new ChunkQube[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];
	private ArrayList<Float> vertCoords = new ArrayList<Float>();
	private ArrayList<Float> texCoords = new ArrayList<Float>();
	
	private Chunk leftChunk;
	private Chunk rightChunk;
	private Chunk topChunk;
	private Chunk bottomChunk;
	private Chunk frontChunk;
	private Chunk backChunk;
	
	private ChunkRenderer parent;
	
	/**
	 * Creates filled chunk.
	 */
	public Chunk(ChunkRenderer parent) {
		this.parent = parent;
		for (byte x = 0; x < CHUNK_SIZE; x++) {
			for (byte z = 0; z < CHUNK_SIZE; z++) {
				for (byte y = 0; y < CHUNK_SIZE; y++) {
					chunkData[x][z][y] = new ChunkQube((byte)1,(byte)2,(byte)2,(byte)2,(byte)2,(byte)0,(byte)1);
				}
			}
		}
		for (byte x = 1; x < CHUNK_SIZE - 1; x++) {
			for (byte z = 1; z < CHUNK_SIZE - 1; z++) {
				for (byte y = 1; y < CHUNK_SIZE - 1; y++) {
					chunkData[x][z][y] = new ChunkQube((byte)0,(byte)2,(byte)2,(byte)2,(byte)2,(byte)0,(byte)1);
				}
			}
		}
		chunkData[2][2][0] = new ChunkQube((byte)0,(byte)2,(byte)2,(byte)2,(byte)2,(byte)0,(byte)1);
	}
	
	public ChunkQube[][][] getChunkData() {
		return chunkData;
	}

	public void setChunkData(ChunkQube[][][] chunkData) {
		this.chunkData = chunkData;
	}

	public ArrayList<Float> getVertCoords() {
		return vertCoords;
	}

	public void setVertCoords(ArrayList<Float> coords) {
		this.vertCoords = coords;
	}

	public ArrayList<Float> getTexCoords() {
		return texCoords;
	}

	public void setTexCoords(ArrayList<Float> texCoords) {
		this.texCoords = texCoords;
	}
	
	public void setLeftChunk(Chunk chunk) {
		leftChunk = chunk;
	}
	
	public void setRightChunk(Chunk chunk) {
		rightChunk = chunk;
	}
	
	public void setTopChunk(Chunk chunk) {
		topChunk = chunk;
	}
	
	public void setBottomChunk(Chunk chunk) {
		bottomChunk = chunk;
	}
	
	public void setFrontChunk(Chunk chunk) {
		frontChunk = chunk;
	}

	public void setBackChunk(Chunk chunk) {
		backChunk = chunk;
	}

	public void buildChunkMesh() {
		for (int x = 0; x < CHUNK_SIZE; x++) {
			for (int y = 0; y < CHUNK_SIZE; y++) {
				for (int z = 0; z < CHUNK_SIZE; z++) {
					if (chunkData[x][y][z].filled() == 1) {
						int topY = y + 1;
						
						//for top chunk
						byte topQube;
						if (topY > CHUNK_SIZE - 1)
							if (topChunk == null)
								topQube = 0;
							else
								topQube = topChunk.getChunkData()[x][0][z].filled();
						else
							topQube = chunkData[x][topY][z].filled();
						
						// current qube on top or top quard is empty, so its top enge is visible
						//if ((topY > CHUNK_SIZE - 1) || chunkData[x][topY][z] == 0) {
						if (topQube == 0) {
							float quardY = (y + 0.5f) * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f;
							// x
							// y
							// z
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							
							float[][] textCoords = parent.getTextureAtlas().getTextCoords(chunkData[x][y][z].topTexture());
							texCoords.add(textCoords[0][0]);
							texCoords.add(textCoords[0][1]);
							texCoords.add(textCoords[1][0]);
							texCoords.add(textCoords[1][1]);
							texCoords.add(textCoords[2][0]);
							texCoords.add(textCoords[2][1]);
							texCoords.add(textCoords[3][0]);
							texCoords.add(textCoords[3][1]);
						}

						int botY = y - 1;
						
						//for bottom chunk
						byte botQube;
						if (botY < 0)
							if (bottomChunk == null)
								botQube = 0;
							else
								botQube = bottomChunk.getChunkData()[x][CHUNK_SIZE - 1][z].filled();
						else
							botQube = chunkData[x][botY][z].filled();
						
						// current qube on bot or bot quard is empty, so its bot edge is visible
						//if ((botY < 0) || chunkData[x][botY][z] == 0) {
						if (botQube == 0) {
							float quardY = (y + 0.5f) * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f;

							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);

							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);

							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);

							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardY);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);

							float[][] textCoords = parent.getTextureAtlas().getTextCoords(chunkData[x][y][z].bottomTexture());
							texCoords.add(textCoords[0][0]);
							texCoords.add(textCoords[0][1]);
							texCoords.add(textCoords[1][0]);
							texCoords.add(textCoords[1][1]);
							texCoords.add(textCoords[2][0]);
							texCoords.add(textCoords[2][1]);
							texCoords.add(textCoords[3][0]);
							texCoords.add(textCoords[3][1]);
						}
						int rightX = x + 1;
						
						//for right chunk
						byte rightQube;
						if (rightX > CHUNK_SIZE - 1)
							if (rightChunk == null)
								rightQube = 0;
							else
								rightQube = rightChunk.getChunkData()[0][y][z].filled();
						else
							rightQube = chunkData[rightX][y][z].filled();
						
						// current qube on right or right quard is empty, so its right edge is visible
						//if ((rightX > CHUNK_SIZE - 1) || chunkData[rightX][y][z] == 0) {
						if (rightQube == 0) {
							float quardX = (x + 0.5f) * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f;
							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);

							float[][] textCoords = parent.getTextureAtlas().getTextCoords(chunkData[x][y][z].rightTexture());
							texCoords.add(textCoords[0][0]);
							texCoords.add(textCoords[0][1]);
							texCoords.add(textCoords[1][0]);
							texCoords.add(textCoords[1][1]);
							texCoords.add(textCoords[2][0]);
							texCoords.add(textCoords[2][1]);
							texCoords.add(textCoords[3][0]);
							texCoords.add(textCoords[3][1]);
						}
						int leftX = x - 1;
						
						//for left chunk
						byte leftQube;
						if (leftX < 0)
							if (leftChunk == null)
								leftQube = 0;
							else
								leftQube = leftChunk.getChunkData()[CHUNK_SIZE - 1][y][z].filled();
						else
							leftQube = chunkData[leftX][y][z].filled();
						
						// current qube on right or right quard is empty, so its right edge is visible
						//if ((leftX < 0) || chunkData[leftX][y][z] == 0) {
						if (leftQube == 0) {
							float quardX = (x + 0.5f) * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f;
							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							
							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);

							vertCoords.add(quardX);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((z + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);

							float[][] textCoords = parent.getTextureAtlas().getTextCoords(chunkData[x][y][z].leftTexture());
							texCoords.add(textCoords[0][0]);
							texCoords.add(textCoords[0][1]);
							texCoords.add(textCoords[1][0]);
							texCoords.add(textCoords[1][1]);
							texCoords.add(textCoords[2][0]);
							texCoords.add(textCoords[2][1]);
							texCoords.add(textCoords[3][0]);
							texCoords.add(textCoords[3][1]);
						}

						int frontZ = z + 1;
						
						//for front chunk
						byte frontQube;
						if (frontZ > CHUNK_SIZE - 1)
							if (frontChunk == null)
								frontQube = 0;
							else
								frontQube = frontChunk.getChunkData()[x][y][0].filled();
						else
							frontQube = chunkData[x][y][frontZ].filled();
						
						// current qube on right or right quard is empty, so its right edge is visible
						//if ((frontZ > CHUNK_SIZE - 1) || chunkData[x][y][frontZ] == 0) {
						if (frontQube == 0) {
							float quardZ = (z + 0.5f) * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f;
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);

							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);

							float[][] textCoords = parent.getTextureAtlas().getTextCoords(chunkData[x][y][z].frontTexture());
							texCoords.add(textCoords[0][0]);
							texCoords.add(textCoords[0][1]);
							texCoords.add(textCoords[1][0]);
							texCoords.add(textCoords[1][1]);
							texCoords.add(textCoords[2][0]);
							texCoords.add(textCoords[2][1]);
							texCoords.add(textCoords[3][0]);
							texCoords.add(textCoords[3][1]);
						}
						int backZ = z - 1;
						
						//for back chunk
						byte backQube;
						if (backZ < 0)
							if (backChunk == null)
								backQube = 0;
							else
								backQube = backChunk.getChunkData()[x][y][CHUNK_SIZE - 1].filled();
						else
							backQube = chunkData[x][y][backZ].filled();
						
						// current qube on right or right quard is empty, so its right edge is visible
						//if ((backZ < 0) || chunkData[x][y][backZ] == 0) {
						if (backQube == 0) {
							float quardZ = (z + 0.5f) * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f;
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);
							
							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE - CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);

							vertCoords.add((x + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add((y + 0.5f)  * CHUNK_GL_SIZE + CHUNK_GL_SIZE * 0.5f);
							vertCoords.add(quardZ);

							float[][] textCoords = parent.getTextureAtlas().getTextCoords(chunkData[x][y][z].backTexture());
							texCoords.add(textCoords[0][0]);
							texCoords.add(textCoords[0][1]);
							texCoords.add(textCoords[1][0]);
							texCoords.add(textCoords[1][1]);
							texCoords.add(textCoords[2][0]);
							texCoords.add(textCoords[2][1]);
							texCoords.add(textCoords[3][0]);
							texCoords.add(textCoords[3][1]);
						}
					}
				}
			}
		}

	}
}
